package com.aqie.libfactory;


import android.util.Log;

import com.aqie.libcommon.app.BaseApplication;
import com.aqie.libcommon.factory.data.DataSource;
import com.aqie.libfactory.data.message.MessageCenter;
import com.aqie.libfactory.data.message.MessageDispatcher;
import com.aqie.libfactory.data.user.UserCenter;
import com.aqie.libfactory.data.user.UserDispatcher;
import com.aqie.libfactory.model.api.RspModel;
import com.aqie.libfactory.model.api.websocket.MessageDTO;
import com.aqie.libfactory.model.api.websocket.SendMessageModel;
import com.aqie.libfactory.model.card.MessageCard;
import com.aqie.libfactory.persistence.Account;
import com.aqie.libfactory.utils.DBFlowExclusionStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.raizlabs.android.dbflow.config.FlowConfig;
import com.raizlabs.android.dbflow.config.FlowManager;
import com.zhangke.websocket.SimpleListener;
import com.zhangke.websocket.WebSocketHandler;
import com.zhangke.websocket.WebSocketManager;
import com.zhangke.websocket.WebSocketSetting;
import com.zhangke.websocket.response.ErrorResponse;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;



public class Factory extends SimpleListener {
    private static final String TAG = Factory.class.getSimpleName();
    // 单例模式
    private static final Factory instance;
    // 全局的线程池
    private final Executor executor;
    // 全局的Gson
    private final Gson gson;


    static {
        instance = new Factory();
    }

    private Factory() {
        // 新建一个4个线程的线程池
        executor = Executors.newFixedThreadPool(4);
        gson = new GsonBuilder()
                // 设置时间格式
                // .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                // 设置一个过滤器，数据库级别的Model不进行Json转换
                .setExclusionStrategies(new DBFlowExclusionStrategy())
                .create();
    }

    public static Factory getInstance() {
        return instance;
    }

    /**
     * Factory 中的初始化
     */
    public static void setup() {
        // 初始化数据库
        FlowManager.init(new FlowConfig.Builder(app())
                .openDatabasesOnInit(true) // 数据库初始化的时候就开始打开
                .build());

        // 持久化的数据进行初始化
        Account.load(app());

        initWebsocket();
    }


    static void initWebsocket(){
        WebSocketSetting setting = new WebSocketSetting();
        setting.setConnectUrl("ws://47.104.240.41:8085/webSocket");
        //设置连接超时时间
        setting.setConnectTimeout(10 * 1000);
        //设置心跳间隔时间
        setting.setConnectionLostTimeout(5);
        //设置断开后的重连次数，可以设置的很大，不会有什么性能上的影响
        setting.setReconnectFrequency(40);
        //通过 init 方法初始化默认的 WebSocketManager 对象
        WebSocketManager manager = WebSocketHandler.init(setting);
        //启动连接
        manager.start();
        manager.addListener(Factory.getInstance());
        // 获取WebsocketManager

        // 进行websocket 登录
        /*WebsocketLoginModel loginModel = new WebsocketLoginModel();
        loginModel.setExpand(Account.getToken());
        manager.send(JSONArray.toJSON(loginModel).toString());*/
    }

    /**
     * websocket 相关
     */
    @Override
    public void onConnected() {
        super.onConnected();
        Log.e(TAG, "onConnected");
    }

    @Override
    public <T> void onMessage(String message, T data) {
        super.onMessage(message, data);
        Log.e(TAG, "oMessage: " + message);

        dispatchPush(message);
    }

    @Override
    public void onSendDataError(ErrorResponse errorResponse) {
        super.onSendDataError(errorResponse);
        Log.e(TAG, "onSendDataError: " + errorResponse.getDescription());
    }

    /**
     * 返回全局的Application
     *
     * @return Application
     */
    public static BaseApplication app() {
        return BaseApplication.getInstance();
    }


    /**
     * 异步运行的方法
     *
     * @param runnable Runnable
     */
    public static void runOnAsync(Runnable runnable) {
        // 拿到单例，拿到线程池，然后异步执行
        instance.executor.execute(runnable);
    }

    /**
     * 返回一个全局的Gson，在这可以进行Gson的一些全局的初始化
     *
     * @return Gson
     */
    public static Gson getGson() {
        return instance.gson;
    }


    /**
     * 进行错误Code的解析，
     * 把网络返回的Code值进行统一的规划并返回为一个String资源
     *
     * @param model    RspModel
     * @param callback DataSource.FailedCallback 用于返回一个错误的资源Id
     */
    public static void decodeRspCode(RspModel model, DataSource.FailedCallback callback) {
        if (model == null)
            return;

        // 进行Code区分
        switch (model.getCode()) {
            case RspModel.SUCCEED:
                return;
            default:
                decodeRspCode(model.getMsg(),callback);
                break;
        }
    }

    private static void decodeRspCode(final String errMsg,
                                      final DataSource.FailedCallback callback) {
        if (callback != null)
            callback.onDataNotAvailable(errMsg);
    }


    /**
     * 收到账户退出的消息需要进行账户退出重新登录
     */
    private void logout() {
        BaseApplication.showToast("您的账号在其他设备登录");
        Account.logOut(BaseApplication.getInstance());
        BaseApplication.getInstance().finishAll();
    }


    /**
     * todo 处理推送来的消息
     *
     * @param str 消息
     */
    public static void dispatchPush(String str){
        SendMessageModel sendMessageModel = getGson().fromJson(str, SendMessageModel.class);
        if(sendMessageModel.getAction() != 2){
            return;
        }
        MessageDTO message = sendMessageModel.getMessage();
        // Log.e(TAG, "dispatchPush " + message);
        MessageCard card = new MessageCard(message);
        getMessageCenter().dispatch(card);

        // 签收消息
        /*SignMessageModel signMessageModel = new SignMessageModel();
        signMessageModel.setExpand(message.getMsgId());
        WebSocketManager manager = WebSocketHandler.getDefault();
        manager.send(JSONArray.toJSON(signMessageModel).toString());*/

    }


    /**
     * 获取一个消息中心的实现类
     *
     * @return 消息中心的规范接口
     */
    public static MessageCenter getMessageCenter() {
        return MessageDispatcher.instance();
    }




    /**
     * todo 获取一个群处理中心的实现类
     *
     * @return 群中心的规范接口
     */


    /**
     * 获取一个用户中心的实现类
     *
     * @return 用户中心的规范接口
     */
    public static UserCenter getUserCenter() {
        return UserDispatcher.instance();
    }

}
